package com.liqi.common.utils.uuid;

import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import java.security.SecureRandom;
import java.util.*;

public class CodeUtils {
	/**
     * 自定义进制(0,1没有加入,容易与o,l混淆)，数组顺序可进行调整增加反推难度，A用来补位因此此数组不包含A，共31个字符。
     */
    private static final char[] BASE = new char[]{'H', 'V', 'E', '8', 'S', '2', 'D', 'Z', 'X', '9', 'C', '7', 'P',
            '5', 'I', 'K', '3', 'M', 'J', 'U', 'F', 'R', '4', 'W', 'Y', 'L', 'T', 'N', '6', 'B', 'G', 'Q'};

    /**
     * A补位字符，不能与自定义重复
     */
    private static final char SUFFIX_CHAR = 'A';

    /**
     * 进制长度
     */
    private static final int BIN_LEN = BASE.length;

    /**
     * 生成邀请码最小长度
     */
    private static final int CODE_LEN = 10;

    public static String code() {

        //指定生成码的固定开头，char[] BASE中下标索引对应值，
        long startCode = 1L;
        char[] buf = new char[BIN_LEN];
        int charPos = BIN_LEN;

        // 当id除以数组长度结果大于0，则进行取模操作，并以取模的值作为数组的坐标获得对应的字符
        while (startCode / BIN_LEN > 0) {
            int index = (int) (startCode % BIN_LEN);
            buf[--charPos] = BASE[index];
            startCode /= BIN_LEN;
        }

        buf[--charPos] = BASE[(int) (startCode % BIN_LEN)];
        // 将字符数组转化为字符串
        String result = new String(buf, charPos, BIN_LEN - charPos);

        // 长度不足指定长度则随机补全
        int len = result.length();
        if (len < CODE_LEN) {
            StringBuilder sb = new StringBuilder();
            sb.append(SUFFIX_CHAR);
            SecureRandom random = new SecureRandom();
            // 去除SUFFIX_CHAR本身占位之后需要补齐的位数
            for (int i = 0; i < CODE_LEN - len - 1; i++) {
                sb.append(BASE[random.nextInt(BIN_LEN)]);
            }

            result += sb.toString();
        }

        return result;
    }

    public static List<String> orderCode(int num) {
        HashSet<String> codes = new HashSet<>();
        while (codes.size() < num) {
            String code = code();
            code = "T" + code.substring(1, 8);
            codes.add(code);
        }
        return new ArrayList<>(codes);
    }

    public static List<String> customerOrderCode(int num) {
        HashSet<String> codes = new HashSet<>();
        while (codes.size() < num) {
            String code = code();
            codes.add(code);
        }
        return new ArrayList<>(codes);
    }

    public static String ticketTypeCode(List<String> list) {
        Map<String, String> map = new HashMap<>();
        if (!CollectionUtils.isEmpty(list)) {
            for (String str : list) {
                map.put(str, str);
            }
        }
        while (true) {
            String code = code();
            code = "C" + code.substring(1, 5);
            if (StringUtils.isBlank(map.get(code))) {
                return code;
            }
        }
    }

    public static String decodeBASE64(String code){
        return new String(Base64.getDecoder().decode(code));
    }

    public static String encodeBASE64(String code) {
        return new String(Base64.getEncoder().encode(code.getBytes()));
    }
    
    private static byte[] lock = new byte[0];
    
	// 位数，默认是8位
	private final static long w = 100000000;
 
	public static String createID() {
		long r = 0;
		synchronized (lock) {
            SecureRandom secureRandom = new SecureRandom();
			r = (long) ((secureRandom.nextInt() + 1) * w);
		}
 
		return System.currentTimeMillis() + String.valueOf(r).substring(1);
	}


    
    public static void main(String[] args) {
        List<String> list = orderCode(2);
        System.out.println(list);
        
        String code = code();
        System.out.println("old:"+code);
        code = "T" + code.substring(1, 8);
        
        System.out.println(code);
        
        
        String id = createID() ;
        
        System.out.println(id);
    }

}
